using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using Spring.Data.NHibernate;
using NHibernate;

namespace Bamboo.Core.Data
{
    public class HibernatePagingQuery : IHibernateCallback
    {
        private long totalRecord;
        private int currentPage;
        private int pageSize;
        private string hql;
        private IList parameterNameList;
        private IList parameterValueList;

        public IList ParameterValueList
        {
            get { return parameterValueList; }
            set { parameterValueList = value; }
        }
	
        public IList ParameterNameList
        {
            get { return parameterNameList; }
            set { parameterNameList = value; }
        }
	
	    public string HQL
	    {
		    get { return hql;}
		    set { hql = value;}
	    }
	
        private SortDirection sortDirection;
        public HibernatePagingQuery(string hql,int pageSize, int currentPage)
        {
            this.hql = hql;
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public HibernatePagingQuery(string hql, string[] parameterNames, object[] parameterValues, int pageSize, int currentPage)
        {
            this.hql = hql;
            this.parameterNameList = new ArrayList();
            if (parameterValues != null && parameterNames != null)
            {
                foreach (string parameterName in parameterNames)
                {
                    this.parameterNameList.Add(parameterName);
                }
                this.parameterValueList = new ArrayList();
                foreach (object parameterValue in parameterValues)
                {
                    this.parameterValueList.Add(parameterValue);
                }
            }
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public HibernatePagingQuery(string hql, string parameterName, object parameterValue, int pageSize, int currentPage)
        {
            this.hql = hql;
            this.parameterNameList = new ArrayList();
            this.parameterNameList.Add(parameterName);
            this.parameterValueList = new ArrayList();
            this.parameterValueList.Add(parameterValue);
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }
        public HibernatePagingQuery(string hql, IList parameterNameList, IList parameterValueList,  int pageSize, int currentPage)
        {
            this.hql = hql;
            this.parameterNameList = parameterNameList;
            this.parameterValueList = parameterValueList;
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public SortDirection SortDirection
        {
            get { return sortDirection; }
            set { sortDirection = value; }
        }


        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        public int CurrentPage
        {
            get { return currentPage; }
            set { currentPage = value; }
        }

        public long TotalRecord
        {
            get { return totalRecord; }
            set { totalRecord = value; }
        }

        
        public object DoInHibernate(NHibernate.ISession session)
        {
            string countQueryString = "select count(*) ";
            int indexOfFromClause = hql.IndexOf("from");
            //get the phrase after from 
            string fromClause = hql.Substring(indexOfFromClause);
            //remove the order by clause in from clause
            int indexOfOrderByClause = fromClause.IndexOf("order by");
            if (indexOfOrderByClause != -1)
            {
                fromClause = fromClause.Substring(0, fromClause.Length - indexOfOrderByClause);
            }
            countQueryString += " " + fromClause;
            IQuery countQuery = session.CreateQuery(countQueryString);
            object totalRecordResult = countQuery.UniqueResult();
            if (totalRecordResult != null)
            {
                totalRecord = long.Parse(totalRecordResult.ToString());
            }

            IQuery query = session.CreateQuery(hql);
            if (parameterNameList != null)
            {
                for (int i = 0; i < parameterNameList.Count; i++)
                {
                    query.SetParameter((string) parameterNameList[i], parameterValueList[i]);
                }
            }
            if (pageSize != -1 && currentPage != -1)
            {
                query.SetFirstResult(currentPage * pageSize);
                query.SetMaxResults(pageSize);
            }

            return query.List();
        }

    }
}
